home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / DELPHI32 / GRIDS / MSTRGRID / MSTRGRID.PAS < prev    next >
Pascal/Delphi Source File  |  1996-06-17  |  23KB  |  600 lines

  1. unit mStrGrid;
  2.  
  3. (* Version 1.0,  17.6.1996,  Freeware, Albrecht Mengel, mengel@stat-econ.uni-kiel.de
  4.  
  5. This is a component descending from TStringGrid with some new sorting and searching properties & methods:
  6.  
  7. procedure InsertCols(where,howmuch:Integer);
  8. procedure InsertRows(where,howmuch:Integer);
  9. procedure DeleteCols(where,howmuch:Integer);
  10. procedure DeleteRows(where,howmuch:Integer);
  11.    It does not matter if there are less rows/cols than you want to delete.
  12. procedure AddCol(contents:String;  delimiter:Char);
  13. procedure AddRow(contents:String;  delimiter:Char);
  14.    The contents are splitted into the single cells by the delimiter
  15. function ModifyRow(which:integer; contents,delimiter:string):integer;
  16.    Results in the number of columns
  17. function ModifyCol(which:integer; contents,delimiter:string):integer;
  18.    Results in the number of rows
  19.  
  20. The following properties control sorting and searching:
  21.  
  22. property KeyType:(soString,soStringCaseSensitive,soNumeric)
  23.    This is the kind, how the keys (and cells) are compared.
  24.    If you work with soNumeric, all non numbers get the same value 0.
  25.       As these zero values would flip in random order a (case insensitive) string sort
  26.       is performed after. So, first come the negatives, then the strings, and thereafter
  27.       the positives.
  28. property KeyPos:Integer;
  29. property KeyLen:Integer;
  30.    Here you may define, which substring of the cells is used to comparision.
  31.    (Default is KeyPos=1 & KeyLen=MaxInt)
  32. property UseFixed:(hfNot,hfSmart,hfYes);
  33.    hfNot: The fixed rows/columns remain as they are (and are not used in searching)
  34.    hfSmart: When sorting complete rows, the fixed columns are part of the rows and
  35.             change their contents in the same manner as the rows are exchanged.
  36.             The top row (fixed rows) remain intact.
  37.             When sorting complete columns, the fixed rows change and the fixed columns not.
  38.             When sorting (single) row/column, hfSmart protects the fixed part of the row/column.
  39.    hfYes: All sorting includes the fixed columns and rows (as if they were set to 0)
  40.  
  41. procedure SortCompleteColumns(KeyRow:integer);
  42. procedure SortCompleteRows(KeyCol:integer);
  43. procedure SortRow(ThisRow:integer);
  44. procedure SortCol(ThisCol:integer);
  45. procedure SortAllRows;
  46.    The rows are sorted independand
  47. procedure SortAllCols;
  48.    The columns are sorted independand
  49.  
  50. Searching can be done with the fixed substrings of cells
  51.    (set SearchSubstring=true and use KeyPos and KeyLen) or
  52.    anywhere in the cells (SearchSubstring=false)
  53. property SearchSubstring:Boolean;
  54.  
  55. function FindFirst(Key:String; RowWise:Boolean; VAR ResultCol,ResultRow:Integer):Boolean;
  56.     Searches all cells, if UseFixed=hfYes or excludes the fixed cells, if UseFixed=hfNo.
  57.     If UseFixed=hfSmart, then the fixed cols are used if searching rowwise or
  58.                               the fixed rows are used if not searching rowwise.
  59.     All finding methods result in true, when a cell was found.
  60.     If nothing found then ResultCol and ResultRow are set to -1.
  61. function FindFirstInRow(Key:String; searchRow:Integer; VAR ResultCol,ResultRow:Integer):Boolean;
  62.     The same as FindFirst, but only one row is used for searching.
  63.     UseFixed=hfSmart is here the same as hfNo.
  64. function FindFirstInCol(Key:String; searchCol:Integer; VAR ResultCol,ResultRow:Integer):Boolean;
  65. function FindNext(VAR ResultCol,ResultRow:Integer):Boolean;
  66.  
  67. A sample searching program:
  68.  if FindFirst('steven',true{rowwise},c,r) then
  69.  repeat memo1.lines.add('Found in cells['+inttostr(c)+','+inttostr(r)+'] = "'+cells[c,r]+'"');
  70.  until not FindNext(c,r);
  71.  
  72. File can be read to or written from the table as ASCII file.
  73. The second parameter is the column delimiter in every row.
  74.     procedure LoadFromFile(FileName,ColSep:string);
  75.     procedure SaveToFile(FileName,ColSep:String);
  76.  
  77. The demo program has one odd property: if found something in the fixed parts of the grid,
  78. the fixed rows/cols are duplicated. (Because it is not allowed to set the cursor there to)
  79.  
  80. The file mStrList is required for compilation.
  81. It contains a 'sister' of TStringList, which can sort in the above manner and is a complete copy
  82. of TStringList, which can be found in \source\vcl\GRIDS.PAS.
  83. But I had a problem with compiling it completely.
  84. If you are good in programming OOP / VCL then please have a look in mStrList.pas and
  85. help me fixing the problem. Until now all seems to work.
  86.  
  87. To install mStrGrid:
  88.  
  89. 1. Copy mStrGrid.* and mStrList.* to a directory for your special delphi components.
  90. 2. Select the Component: Install menu.
  91. 3. Click the Add button.
  92. 4. Click the Browse button.
  93. 5. Locate and select the mStrGrid.pas file
  94. 6. Click the Ok buttons to close all the dialogs.
  95. The Delphi component library DLL will be recompiled with the new mStrGrid component
  96. added to the Additional page of the component palette.
  97.  
  98. Software development:
  99.  
  100. Programming consumes time, and programmed components save time.
  101. If you like my components feel free to send me some acknowledgment.
  102. I accept post cards of your town, money or cheques (2$ up to 20$).
  103. This is a motivation for me to continue developing for you.
  104.  
  105. If you have some ideas to improve mStrList, mStrGrid or any other component
  106. send me a message.
  107.  
  108. The component is copyright (C) 1996, by Albrecht Mengel. You may give copies to
  109. others by copying the original, unmodified zip file. You may use this component
  110. in your own projects free of charge as long as those projects are public domain,
  111. freeware or shareware project.
  112.  
  113. The author of mStrList and mStrGrid (A. Mengel) makes no warranty of any kind,
  114. expressed or implied, including without limitation any warranties of merchantability
  115. and/or fitness for a particular purpose. In no event will the author be liable to you
  116. for any additional damages, including any lost profits, lost savings, or other
  117. incidental or consequential damages arising from the use of, or inability to use,
  118. this software and its accompanying documentation, even if the author has been advised
  119. of the possibility of such damages.
  120.  
  121. Albrecht Mengel, University of Kiel, Germany
  122. Institute for Statistics & Economics
  123. Olshausenstrasse 40-60,
  124. D-24098 Kiel
  125. Tel. +49-431-880-2424
  126. Fax. +49-431-880-2673
  127. Email: mengel@stat-econ.uni-kiel.de
  128. http://www.stat-econ.uni-kiel.de/pers/mengel.htm
  129. *)
  130.  
  131. interface
  132.  
  133. uses
  134.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  135.   Grids, mStrList;
  136.  
  137. type
  138.   HandleFixed = (hfNot,hfSmart,hfYes);
  139.   TmStrGrid = class(TStringgrid)
  140.   private
  141.     { Private-Deklarationen }
  142.     fKeyType:TMSortType;
  143.     fKeyPos:Integer;
  144.     fKeyLen:Integer;
  145.     fUseFixed:HandleFixed;
  146.     SearchKey:String;
  147.     FirstSearchRow,FirstSearchCol,ActSearchRow,ActSearchCol,LastSearchRow,LastSearchCol:Integer;
  148.     SearchRowWise,SearchIsActive:Boolean;
  149.     fSearchSubstring:Boolean;
  150.   protected
  151.     { Protected-Deklarationen }
  152.   public
  153.     { Public-Deklarationen }
  154.     constructor Create(AOwner: TComponent);override;
  155.   published
  156.     { Published-Deklarationen }
  157.     procedure InsertCols(where,howmuch:Integer);
  158.     procedure InsertRows(where,howmuch:Integer);
  159.     procedure DeleteCols(where,howmuch:Integer);
  160.     procedure DeleteRows(where,howmuch:Integer);
  161.     procedure AddRow(contents:String; delimiter:Char);
  162.     procedure AddCol(contents:String;  delimiter:Char);
  163.     function ModifyRow(which:integer; contents,delimiter:string):integer;
  164.     function ModifyCol(which:integer; contents,delimiter:string):integer;
  165.     function FindFirst(Key:String; RowWise:Boolean; VAR ResultCol,ResultRow:Integer):Boolean;
  166.     function FindFirstInRow(Key:String; searchRow:Integer; VAR ResultCol,ResultRow:Integer):Boolean;
  167.     function FindFirstInCol(Key:String; searchCol:Integer; VAR ResultCol,ResultRow:Integer):Boolean;
  168.     function FindNext(VAR ResultCol,ResultRow:Integer):Boolean;
  169.     procedure SortCompleteColumns(KeyRow:integer);
  170.     procedure SortCompleteRows(KeyCol:integer);
  171.     procedure SortRow(ThisRow:integer);
  172.     procedure SortCol(ThisCol:integer);
  173.     procedure SortAllRows;
  174.     procedure SortAllCols;
  175.     property KeyType:TMSortType read fKeyType write fKeyType;
  176.     property KeyPos:Integer read fKeyPos write fKeyPos;
  177.     property KeyLen:Integer read fKeyLen write fKeyLen;
  178.     property UseFixed:HandleFixed read fUseFixed write fUseFixed;
  179.     procedure LoadFromFile(FileName,ColSep:string);
  180.     procedure SaveToFile(FileName,ColSep:String);
  181.     property SearchSubstring:Boolean read fSearchSubstring write fSearchSubstring;
  182.   end;
  183.  
  184.   MFileError = class(Exception);
  185.  
  186. procedure Register;
  187.  
  188. implementation
  189.  
  190. procedure Register;
  191. begin
  192.   RegisterComponents('Additional', [TmStrGrid]);
  193. end;
  194.  
  195. FUNCTION rVAL(CONST von:String):Real;
  196.   {Reads a real value out of the string without an error message.
  197.    Returns 0 if no numeric value}
  198.   VAR bis,err:Integer; nach:Real;
  199.   BEGIN VAL(von,nach,bis);
  200.       IF bis>0 THEN VAL(copy(von,1,bis-1),nach,err);
  201.       rVAL:=nach
  202.   END;{rVAL}
  203.  
  204. constructor TmStrGrid.Create(AOwner: TComponent);
  205. begin inherited Create(AOwner);
  206.       fKeyType:=soString;
  207.       fKeyPos:=1;
  208.       fKeyLen:=MaxInt;
  209. end;
  210.  
  211. procedure TmStrGrid.SortCompleteColumns(KeyRow:integer);
  212. {Spalten sortieren nach der Zeile KeyRow}
  213. var i,j,k,rowanfang,colanfang:integer; index:TMStrList; puffer:TStringList;
  214. begin case fUseFixed of
  215.        hfNot  :begin rowanfang:=FixedRows; colanfang:=FixedCols end;
  216.        hfSmart:begin rowanfang:=0;         colanfang:=FixedCols end;
  217.        {hfYes} else  rowanfang:=0;         colanfang:=0
  218.       end;
  219.       index:=TMStrList.create;
  220.       index.KeyPos:=fKeyPos;
  221.       index.KeyLen:=fKeyLen;
  222.       index.KeyType:=fKeyType;
  223.       index.ScipFirst:=colanfang;
  224.       puffer:=TStringList.create;
  225.       {Schlⁿsselzeile holen}
  226.       index.addstrings(Rows[KeyRow]);
  227.       {Sortierindizees bilden}
  228.       for i:=0 to colcount-1 do
  229.        index.objects[i]:=TObject(i);
  230.       {Liste sortieren}
  231.       index.sorted:=true;
  232.       index.sorted:=false;
  233.       {Zeilen vertauschen}
  234.       repeat {Suche einen Zyklus}
  235.              i:=0;
  236.              with index do
  237.              begin while (i<count) and (i=integer(objects[i])) do inc(i);
  238.                    if i=count then break;
  239.                    {Tausche Zyklus}
  240.                    puffer.clear;
  241.                    puffer.addstrings(cols[i]);
  242.                    repeat j:=Integer(objects[i]);
  243.                           objects[i]:=TObject(i);
  244.                           if integer(objects[j])=j then break;
  245.                           for k:=rowanfang to RowCount-1 do
  246.                             cells[i,k]:=cells[j,k];
  247.                           i:=j;
  248.                    until false;
  249.              end;
  250.              for k:=rowanfang to RowCount-1 do
  251.                begin cells[i,k]:=puffer.strings[k];
  252.                      objects[i,k]:=puffer.objects[k]
  253.                end;
  254.       until false;
  255.       index.free;
  256.       puffer.free
  257. end;
  258.  
  259. procedure TmStrGrid.SortCompleteRows(KeyCol:integer);
  260. {Zeilen sortieren nach der Spalte KeyCol}
  261. var i,j,k,rowanfang,colanfang:integer; index:TMStrList; puffer:TStringList;
  262. begin case fUseFixed of
  263.        hfNot  :begin rowanfang:=FixedRows; colanfang:=FixedCols end;
  264.        hfSmart:begin rowanfang:=FixedRows; colanfang:=0 end;
  265.        {hfYes} else  rowanfang:=0;         colanfang:=0
  266.       end;
  267.       index:=TMStrList.create;
  268.       index.KeyPos:=fKeyPos;
  269.       index.KeyLen:=fKeyLen;
  270.       index.KeyType:=fKeyType;
  271.       index.ScipFirst:=rowanfang;
  272.       puffer:=TStringList.create;
  273.       {Schlⁿsselspalte holen}
  274.       index.addstrings(cols[KeyCol]);
  275.       {Sortierindizees bilden}
  276.       for i:=0 to rowcount-1 do
  277.        index.objects[i]:=TObject(i);
  278.       {Liste sortieren}
  279.       index.sorted:=true;
  280.       index.sorted:=false;
  281.       {Zeilen vertauschen}
  282.       repeat {Suche einen Zyklus}
  283.              i:=0;
  284.              with index do
  285.              begin while (i<count) and (i=integer(objects[i])) do inc(i);
  286.                    if i=count then break;
  287.                    {Tausche Zyklus}
  288.                    puffer.clear;
  289.                    puffer.addstrings(rows[i]);
  290.                    repeat j:=Integer(objects[i]);
  291.                           objects[i]:=TObject(i);
  292.                           if integer(objects[j])=j then break;
  293.                           for k:=colanfang to ColCount-1 do
  294.                             cells[k,i]:=cells[k,j];
  295.                           i:=j;
  296.                    until false;
  297.              end;
  298.              for k:=colanfang to ColCount-1 do
  299.                begin cells[k,i]:=puffer.strings[k];
  300.                      objects[k,i]:=puffer.objects[k]
  301.                end;
  302.       until false;
  303.       index.free;
  304.       puffer.free
  305. end;
  306.  
  307. procedure TmStrGrid.SortRow(ThisRow:integer);
  308. var colanfang:integer; index:TMStrList;
  309. begin case fUseFixed of
  310.        hfNot  :colanfang:=FixedCols;
  311.        hfSmart:colanfang:=FixedCols; else
  312.        {hfYes} colanfang:=0
  313.       end;
  314.       index:=TMStrList.create;
  315.       index.KeyPos:=fKeyPos;
  316.       index.KeyLen:=fKeyLen;
  317.       index.KeyType:=fKeyType;
  318.       index.ScipFirst:=colanfang;
  319.       {Go!}
  320.       index.clear;
  321.       index.addstrings(Rows[ThisRow]);
  322.       index.sorted:=true;
  323.       index.sorted:=false;
  324.       Rows[ThisRow].clear;
  325.       Rows[ThisRow].addstrings(index);
  326. end;
  327.  
  328. procedure TmStrGrid.SortCol(ThisCol:integer);
  329. var rowanfang:integer; index:TMStrList;
  330. begin case fUseFixed of
  331.        hfNot  :rowanfang:=FixedRows;
  332.        hfSmart:rowanfang:=FixedRows; else
  333.        {hfYes} rowanfang:=0;
  334.       end;
  335.       index:=TMStrList.create;
  336.       index.KeyPos:=fKeyPos;
  337.       index.KeyLen:=fKeyLen;
  338.       index.KeyType:=fKeyType;
  339.       index.ScipFirst:=rowanfang;
  340.       {Go!}
  341.       index.addstrings(Cols[ThisCol]);
  342.       index.sorted:=true;
  343.       index.sorted:=false;
  344.       Cols[ThisCol].clear;
  345.       Cols[ThisCol].addstrings(index);
  346. end;
  347.  
  348. procedure TmStrGrid.SortAllRows;
  349. {Alle Zeilen unabhΣngig voneinander sortieren}
  350. var i,rowanfang,colanfang:integer; index:TMStrList;
  351. begin case fUseFixed of
  352.        hfNot  :begin rowanfang:=FixedRows; colanfang:=FixedCols end;
  353.        hfSmart:begin rowanfang:=0;       ; colanfang:=FixedCols end;
  354.        {hfYes} else  rowanfang:=0;         colanfang:=0
  355.       end;
  356.       index:=TMStrList.create;
  357.       index.KeyPos:=fKeyPos;
  358.       index.KeyLen:=fKeyLen;
  359.       index.KeyType:=fKeyType;
  360.       index.ScipFirst:=colanfang;
  361.       for i:= Rowanfang to RowCount-1 do
  362.         begin index.clear;
  363.               index.addstrings(Rows[i]);
  364.               index.sorted:=true;
  365.               index.sorted:=false;
  366.               Rows[i].clear;
  367.               Rows[i].addstrings(index);
  368. end     end;
  369.  
  370. procedure TmStrGrid.SortAllCols;
  371. {Alle Spalten unabhΣngig voneinander sortieren}
  372. var i,rowanfang,colanfang:integer; index:TMStrList;
  373. begin case fUseFixed of
  374.        hfNot  :begin rowanfang:=FixedRows; colanfang:=FixedCols end;
  375.        hfSmart:begin rowanfang:=FixedRows; colanfang:=0 end;
  376.        {hfYes} else  rowanfang:=0;         colanfang:=0
  377.       end;
  378.       index:=TMStrList.create;
  379.       index.KeyPos:=fKeyPos;
  380.       index.KeyLen:=fKeyLen;
  381.       index.KeyType:=fKeyType;
  382.       index.ScipFirst:=rowanfang;
  383.       for i:= colanfang to ColCount-1 do
  384.         begin index.clear;
  385.               index.addstrings(Cols[i]);
  386.               index.sorted:=true;
  387.               index.sorted:=false;
  388.               Cols[i].clear;
  389.               Cols[i].addstrings(index);
  390. end     end;
  391.  
  392. function TmStrGrid.ModifyRow(which:integer; contents,delimiter:string):integer;
  393. var p,c,len:integer;
  394. begin c:=0;
  395.       len:=length(delimiter)-1;
  396.       repeat p:=pos(delimiter,contents);
  397.              if p=0 then break;
  398.              cells[c,which]:=copy(contents,1,p-1);
  399.              system.delete(contents,1,p+len);
  400.              inc(c)
  401.       until false;
  402.       cells[c,which]:=contents;
  403.       ModifyRow:=c+1
  404. end;
  405.  
  406. function TmStrGrid.ModifyCol(which:integer; contents,delimiter:string):integer;
  407. var p,r,len:integer;
  408. begin r:=0;
  409.       len:=length(delimiter)-1;
  410.       repeat p:=pos(delimiter,contents);
  411.              if p=0 then break;
  412.              cells[which,r]:=copy(contents,1,p-1);
  413.              system.delete(contents,1,p+len);
  414.              inc(r)
  415.       until false;
  416.       cells[which,r]:=contents;
  417.       ModifyCol:=r+1
  418. end;
  419.  
  420. procedure TmStrGrid.LoadFromFile(FileName,ColSep:string);
  421. var f:textfile; zeile:string; MaxCol,z,s:integer;
  422. begin assignfile(f,FileName);
  423.       reset(f);
  424.       if IOResult <> 0 then
  425.         raise MFileError.Create('File '+Filename+' not found');
  426.       z:=-1;
  427.       MaxCol:=0;
  428.       while not eof(f) do
  429.         begin readln(f,zeile);
  430.               if zeile='' then continue;
  431.               inc(z);
  432.               if z>FixedRows then RowCount:=z+1;
  433.               s:=ModifyRow(z,zeile,ColSep);
  434.               if s>MaxCol then MaxCol:=s;
  435.         end;
  436.       RowCount:=z+1;
  437.       ColCount:=MaxCol;
  438.       closefile(f)
  439. end;
  440.  
  441. procedure TmStrGrid.SaveToFile(FileName,ColSep:String);
  442. var f:textfile; z,s:integer;
  443. begin assignfile(f,FileName);
  444.       rewrite(f);
  445.       for z:=0 to RowCount-1 do
  446.         begin for s:=0 to ColCount-1 do
  447.                 begin if s>0 then write(f,ColSep);
  448.                       write(f,cells[s,z]);
  449.                 end;
  450.               writeln(f)
  451.         end;
  452.       closefile(f)
  453. end;
  454.  
  455. procedure TmStrGrid.InsertCols(where,howmuch:Integer);
  456. var i:Integer;
  457. begin ColCount:=ColCount+howmuch;
  458.       for i:=ColCount-1 downto where+howmuch do
  459.         Cols[i]:=Cols[i-howmuch];
  460.       cols[where].clear;
  461.       for i:=where+1 to where+howmuch-1 do
  462.         Cols[i]:=Cols[where];
  463. end;
  464.  
  465. procedure TmStrGrid.InsertRows(where,howmuch:Integer);
  466. var i:Integer;
  467. begin RowCount:=RowCount+howmuch;
  468.       for i:=RowCount-1 downto where+howmuch do
  469.         Rows[i]:=Rows[i-howmuch];
  470.       Rows[where].clear;
  471.       for i:=where+1 to where+howmuch-1 do
  472.         Rows[i]:=Rows[where];
  473. end;
  474.  
  475. procedure TmStrGrid.DeleteCols(where,howmuch:Integer);
  476. var i:Integer;
  477. begin if ColCount-where<howmuch then howmuch:=ColCount-where;
  478.       for i:=where to ColCount-1 do
  479.         Cols[i]:=Cols[i+howmuch];
  480.       ColCount:=ColCount-howmuch;
  481. end;
  482.  
  483. procedure TmStrGrid.DeleteRows(where,howmuch:Integer);
  484. var i:Integer;
  485. begin if RowCount-where<howmuch then howmuch:=RowCount-where;
  486.       for i:=where to RowCount-1 do
  487.         Rows[i]:=Rows[i+howmuch];
  488.       RowCount:=RowCount-howmuch;
  489. end;
  490.  
  491. procedure TmStrGrid.AddRow(contents:String; delimiter:Char);
  492. begin RowCount:=RowCount+1;
  493.       ModifyRow(RowCount-1,contents,delimiter);
  494. end;
  495.  
  496. procedure TmStrGrid.AddCol(contents:String;  delimiter:Char);
  497. begin ColCount:=ColCount+1;
  498.       ModifyCol(ColCount-1,contents,delimiter);
  499. end;
  500.  
  501. function TmStrGrid.FindFirst(Key:String; RowWise:Boolean; VAR ResultCol,ResultRow:Integer):Boolean;
  502. begin SearchKey:=Key; SearchRowWise:=RowWise; SearchIsActive:=true;
  503.       case fUseFixed of
  504.        hfNot:begin FirstSearchRow:=FixedRows; FirstSearchCol:=FixedCols end;
  505.        hfSmart:if rowwise
  506.                then begin FirstSearchRow:=FixedRows; FirstSearchCol:=0; end
  507.                else begin FirstSearchRow:=0; FirstSearchCol:=FixedCols; end;
  508.        hfYes:begin FirstSearchRow:=0; FirstSearchCol:=0 end;
  509.       end;
  510.       ActSearchRow:=FirstSearchRow; LastSearchRow:=RowCount-1;
  511.       ActSearchCol:=FirstSearchCol; LastSearchCol:=ColCount-1;
  512.       FindFirst:=FindNext(ResultCol,ResultRow);
  513. end;
  514.  
  515. function TmStrGrid.FindFirstInRow(Key:String; searchRow:Integer; VAR ResultCol,ResultRow:Integer):Boolean;
  516. begin SearchKey:=Key; SearchRowWise:=true; SearchIsActive:=true;
  517.       FirstSearchRow:=searchRow; ActSearchRow:=searchRow; LastSearchRow:=searchRow;
  518.       if fUseFixed=hfNot
  519.       then FirstSearchCol:=FixedCols
  520.       else FirstSearchCol:=0;
  521.       ActSearchCol:=FirstSearchCol;  LastSearchCol:=ColCount-1;
  522.       FindFirstInRow:=FindNext(ResultCol,ResultRow);
  523. end;
  524.  
  525. function TmStrGrid.FindFirstInCol(Key:String; searchCol:Integer; VAR ResultCol,ResultRow:Integer):Boolean;
  526. begin SearchKey:=Key; SearchRowWise:=false; SearchIsActive:=true;
  527.       FirstSearchCol:=searchCol; ActSearchCol:=searchCol; LastSearchCol:=searchCol;
  528.       if fUseFixed=hfNot
  529.       then FirstSearchRow:=FixedRows
  530.       else FirstSearchRow:=0;
  531.       ActSearchRow:=FirstSearchRow;
  532.       LastSearchRow:=RowCount-1;
  533.       FindFirstInCol:=FindNext(ResultCol,ResultRow);
  534. end;
  535.  
  536. function TmStrGrid.FindNext(VAR ResultCol,ResultRow:Integer):Boolean;
  537. var SearchReal:Real; found:boolean;
  538.   function next:boolean;
  539.   begin next:=false;
  540.         if SearchRowWise
  541.         then begin inc(ActSearchCol);
  542.                    if ActSearchCol>LastSearchCol then
  543.                    begin ActSearchCol:=FirstSearchCol;
  544.                          inc(ActSearchRow);
  545.                          if ActSearchRow>LastSearchRow then exit
  546.              end   end
  547.         else begin inc(ActSearchRow);
  548.                    if ActSearchRow>LastSearchRow then
  549.                    begin ActSearchRow:=FirstSearchRow;
  550.                          inc(ActSearchCol);
  551.                          if ActSearchCol>LastSearchCol then exit
  552.              end   end;
  553.         next:=true
  554.   end;
  555. begin if not SearchIsActive then
  556.         begin FindNext:=false;
  557.               ResultRow:=-1; ResultCol:=-1;
  558.               exit
  559.         end;
  560.       SearchReal:=0;
  561.      {Suchwort konvertieren}
  562.       case fKeyType of
  563.        soNumeric:SearchReal:=Rval(SearchKey);
  564.        soString:if fSearchSubstring then SearchKey:=UpperCase(SearchKey);
  565.       end;
  566.       found:=false;
  567.       if fSearchSubstring then
  568.       repeat {Suche Passenden}
  569.              case fKeyType of
  570.               soString:if pos(SearchKey,UpperCase(cells[ActSearchCol,ActSearchRow]))>0 then
  571.                         begin found:=true; break end;
  572.               soStringCaseSensitive:if pos(SearchKey,cells[ActSearchCol,ActSearchRow])>0 then
  573.                         begin found:=true; break end;
  574.               soNumeric:if Rval(copy(cells[ActSearchCol,ActSearchRow],fKeyPos,fKeyLen))=SearchReal then
  575.                         begin found:=true; break end;
  576.              end;
  577.       until found or not next
  578.       else
  579.       repeat {Suche Passenden}
  580.              case fKeyType of
  581.               soString:if AnsiCompareText(copy(cells[ActSearchCol,ActSearchRow],fKeyPos,fKeyLen),SearchKey)=0 then
  582.                         begin found:=true; break end;
  583.               soStringCaseSensitive:if copy(cells[ActSearchCol,ActSearchRow],fKeyPos,fKeyLen)=SearchKey then
  584.                         begin found:=true; break end;
  585.               soNumeric:if Rval(copy(cells[ActSearchCol,ActSearchRow],fKeyPos,fKeyLen))=SearchReal then
  586.                         begin found:=true; break end;
  587.              end;
  588.       until found or not next;
  589.       if found
  590.        then begin ResultRow:=ActSearchRow; ResultCol:=ActSearchCol;
  591.                   SearchIsActive:=next
  592.             end
  593.        else begin SearchIsActive:=false;
  594.                   ResultRow:=-1; ResultCol:=-1
  595.             end;
  596.       FindNext:=found;
  597. end;
  598.  
  599. end.
  600.